package com.icongyou.enterprise.talent_analysis.service.impl;

import com.icongyou.enterprise.data_aggregation.entity.*;
import com.icongyou.enterprise.data_aggregation.service.DataAggregationService;
import com.icongyou.enterprise.talent_analysis.entity.dto.StudentFeatureContext;
import com.icongyou.enterprise.talent_analysis.entity.dto.StudentFeatureContext.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 学生特征提取器
 * 从数据库聚合学生的多维度数据,构建完整特征上下文
 */
@Component
@RequiredArgsConstructor
public class StudentFeatureExtractor {

    private final DataAggregationService dataAggregationService;

    /**
     * 提取学生完整特征
     */
    public StudentFeatureContext extractFeatures(String studentId) {
        StudentFeatureContext context = new StudentFeatureContext();
        
        // 1. 基础信息
        UserEntity student = dataAggregationService.getStudentById(studentId);
        if (student == null) {
            return context;
        }
        context.setStudentId(studentId);
        context.setStudentName(student.getRealName());
        context.setMajor(student.getMajor());
        context.setClassName(student.getClassName());
        
        // 2. 数值型指标 (原始聚合数据)
        Map<String, Object> rawMetrics = dataAggregationService.getStudentRawMetrics(studentId, 0.6, 120, 7);
        context.setNumericMetrics(rawMetrics);
        
        // 3. 任务维度数据
        List<CourseStudentEntity> courses = dataAggregationService.getStudentCourse(studentId);
        for (CourseStudentEntity course : courses) {
            List<AssignmentStudentEntity> assignmentScores = 
                dataAggregationService.getStudentAssignmentScore(studentId, course.getCourseId());
            
            for (AssignmentStudentEntity as : assignmentScores) {
                List<SubmissionEntity> submissions = 
                    dataAggregationService.getStudentSubmission(studentId, as.getAssignmentId());
                
                for (SubmissionEntity sub : submissions) {
                    List<GradeEntity> grades = dataAggregationService.getStudentGrade(sub.getSubmissionId());
                    if (!grades.isEmpty()) {
                        GradeEntity grade = grades.get(0);
                        AssignmentFeature af = buildAssignmentFeature(sub, grade, studentId);
                        context.getAssignments().add(af);
                    }
                }
            }
        }
        
        // 4. 教师评价
        List<GradeEntity> comments = dataAggregationService.getTeacherComment(studentId);
        for (GradeEntity grade : comments) {
            TeacherComment tc = new TeacherComment();
            tc.setCommentText(grade.getTextComment());
            tc.setScore(grade.getFinalScore());
            tc.setIsRecommended(grade.getIsTeacherRecommended() != null && grade.getIsTeacherRecommended() == 1);
            context.getTeacherComments().add(tc);
        }
        
        // 5. 团队经历
        List<TeamMemberEntity> teams = dataAggregationService.getStudentTeam(studentId);
        for (TeamMemberEntity tm : teams) {
            TeamEntity team = dataAggregationService.getTeamById(tm.getTeamId());
            if (team != null) {
                TeamExperience te = new TeamExperience();
                te.setTeamName(team.getTeamName());
                te.setTeamScore(team.getCurrentScore());
                te.setTeamRanking(team.getRanking());
                fillTeamContributionStats(context, tm.getTeamId(), te);
                context.getTeamExperiences().add(te);
            }
        }
        
        // 6. 学习行为统计
        computeLearningBehavior(context);
        
        // 7. 统计摘要
        computeStatisticalSummary(context, rawMetrics);
        
        return context;
    }

    private AssignmentFeature buildAssignmentFeature(SubmissionEntity sub, GradeEntity grade, String studentId) {
        AssignmentFeature af = new AssignmentFeature();
        af.setAssignmentId(sub.getAssignmentId());
        af.setTeamId(sub.getTeamId());
        af.setFinalScore(grade.getFinalScore());
        af.setActualDuration(sub.getActualDuration());
        af.setIsLate(sub.getIsLate() == 1);
        af.setLikeCount(sub.getLikeCount());
        af.setFavoriteCount(sub.getFavoriteCount());
        // 从 JSON 数组中提取当前学生的贡献率
        if (sub.getContributionRate() != null) {
            for (SubmissionEntity.ContributionItem item : sub.getContributionRate()) {
                if (item.getStudentId().equals(studentId)) {
                    af.setContributionRate(item.getRate());
                    break;
                }
            }
        }
        af.setTeacherTextComment(grade.getTextComment());
        af.setAiComment(grade.getAiTextComment());
        af.setIsTeacherRecommended(grade.getIsTeacherRecommended() == 1);
        return af;
    }

    private void fillTeamContributionStats(StudentFeatureContext context, String teamId, TeamExperience experience) {
        List<AssignmentFeature> relatedAssignments = context.getAssignments().stream()
            .filter(a -> a.getTeamId() != null && a.getTeamId().equals(teamId))
            .collect(Collectors.toList());

        experience.setTaskCount(relatedAssignments.size());

        List<BigDecimal> contributions = relatedAssignments.stream()
            .map(AssignmentFeature::getContributionRate)
            .filter(value -> value != null)
            .collect(Collectors.toList());

        if (!contributions.isEmpty()) {
            BigDecimal sum = contributions.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
            experience.setAvgContribution(sum.divide(BigDecimal.valueOf(contributions.size()), 4, RoundingMode.HALF_UP));
        }
    }

    private void computeLearningBehavior(StudentFeatureContext context) {
        LearningBehavior lb = context.getLearningBehavior();
        List<AssignmentFeature> assignments = context.getAssignments();
        
        lb.setTotalSubmissions(assignments.size());
        lb.setOnTimeSubmissions((int) assignments.stream().filter(a -> !a.getIsLate()).count());
        lb.setLateSubmissions((int) assignments.stream().filter(AssignmentFeature::getIsLate).count());
        lb.setHighScoreCount((int) assignments.stream()
            .filter(a -> a.getFinalScore() != null && a.getFullScore() != null 
                && a.getFinalScore().compareTo(a.getFullScore().multiply(BigDecimal.valueOf(0.9))) >= 0)
            .count());
        
        if (!assignments.isEmpty()) {
            double avgSpeed = assignments.stream()
                .filter(a -> a.getActualDuration() != null && a.getExpectedDuration() != null && a.getExpectedDuration() > 0)
                .mapToDouble(a -> a.getExpectedDuration() * 1.0 / a.getActualDuration())
                .average().orElse(1.0);
            lb.setAvgCompletionSpeed(avgSpeed);
        }
    }

    private void computeStatisticalSummary(StudentFeatureContext context, Map<String, Object> rawMetrics) {
        StatisticalSummary summary = context.getSummary();
        
        List<AssignmentFeature> assignments = context.getAssignments();
        
        // 默认值，防止空指针
        summary.setTotalAssignments(assignments.size());
        summary.setCompletedAssignments(assignments.size());
        
        if (!assignments.isEmpty()) {
            List<BigDecimal> scores = assignments.stream()
                .map(AssignmentFeature::getFinalScore)
                .filter(s -> s != null)
                .collect(Collectors.toList());
            
            if (!scores.isEmpty()) {
                summary.setAvgScore(scores.stream()
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(scores.size()), 2, RoundingMode.HALF_UP));
                summary.setMaxScore(scores.stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO));
                summary.setMinScore(scores.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO));
            }
        } else {
            // 空数据时设置默认值
            summary.setAvgScore(BigDecimal.ZERO);
            summary.setMaxScore(BigDecimal.ZERO);
            summary.setMinScore(BigDecimal.ZERO);
        }
        
        Object onTimeRate = rawMetrics.get("on_time_submission_rate");
        if (onTimeRate != null) {
            summary.setOnTimeRate(((Number) onTimeRate).doubleValue());
        }
        
        Object passRate = rawMetrics.get("assignment_pass_rate");
        if (passRate != null) {
            summary.setPassRate(((Number) passRate).doubleValue());
        }
    }
}
